<!doctype html><head><title>mox-weapp接口说明</title><link rel="stylesheet" href="http://mozigu.net/assets/markdown.css"></head>

<h1>mogo 微信小程序前端基础逻辑封装</h1>
<h1>一、接入方式</h1>
<ul>
<li><p>  mox-weapp 发布在 <a href="http://npm.mozigu.cn">http://npm.mozigu.cn</a> 中，需要对其进行 安装 和 文件转移</p>
</li>
<li><p>在 src/package.json 中添加指令：</p>
<pre><code class="language-json">{
    &quot;mox&quot;: &quot;npm install mox-weapp --registry=http://npm.mozigu.cn &amp;&amp; gulp mox-weapp&quot;
}
</code></pre>
<p>  在 src/gulpfile.js 中添加 task：</p>
<pre><code class="language-javascript">gulp.task(&#39;mox-weapp&#39;, () =&gt; {
    return gulp
        .src([&#39;./node_modules/mox-weapp/**/*.*&#39;, &#39;!./node_modules/mox-weapp/package.json&#39;])
        .pipe(gulp.dest(&#39;./src/mox-weapp&#39;));
});
</code></pre>
<p>  执行命令：</p>
<pre><code class="language-javascript">npm run mox
</code></pre>
<p>  添加 src/global.js, 加入 server 配置：</p>
<pre><code class="language-javascript">export default {
    server: &#39;https://{{SERVER}}&#39;
};
</code></pre>
<p>  此时项目 src 目录应为：</p>
<pre><code>├── assets
├── mox-weapp
├── pages
    ├── index
        ├── index.wxml
        ├── index.less
        ├── index.json
        ├── index.js
    └── ...
├── app.js
├── app.json
├── app.wxss
├── utils
├── global.js
└── ...
</code></pre>
</li>
<li><p>在小程序 app.js 中引入:</p>
<pre><code class="language-javascript">import mox from &#39;./mox-weapp/index.js&#39;;
</code></pre>
</li>
</ul>
<h1>二、接口</h1>
<h2>注：components 引入</h2>
<ul>
<li>  部分功能需要引入 weapp-ui 组件 才能正常调用接口</li>
<li>使用方式：<ul>
<li>引入 weapp-ui:<ul>
<li>在对应页面的 json 文件中引入组件:<pre><code class="language-json">// index.json
&quot;usingComponents&quot;: {
    &quot;weapp-ui&quot;: &quot;/mox-weapp/components/index&quot;
},
</code></pre>
</li>
<li>在页面 wxml 底部，增加节点:<pre><code class="language-html">&lt;!-- index.wxml  --&gt;
&lt;weapp-ui id=&quot;__weapp_ui__&quot;&gt;&lt;/weapp-ui&gt;
</code></pre>
  <font color="red"><strong>注意：标签名、id 不能修改</strong></font></li>
</ul>
</li>
</ul>
</li>
</ul>
<h2>注： 回调支持</h2>
<ul>
<li>  <font color="red"><strong>所有接口的入参 opts 参数均支持 success, fail, complete 回调使用， 后续接口不再列举</strong></font></li>
<li>  <font color="red"><strong>若部分接口不支持，会单独说明</strong></font></li>
<li>示例代码：<pre><code class="language-javascript">mox.login({
    success: () =&gt; {
        // 登录成功
    },
    fail: () =&gt; {
        // 登录失败
    },
    complete: () =&gt; {
        // 无论成功失败，都会在调用完后执行
    }
});
</code></pre>
</li>
<li>  <font color="red" size="4"><strong>注意： mox.request, mox.audio, mox.recorder 暂不支持 callback 方式</strong></font></li>
</ul>
<h2>定制风格</h2>
<h3>mox.theme</h3>
<ul>
<li>  mox.theme 设计用来支持项目的 UI 定制配置，weapp-js 内部实现时，凡是支持外部定制风格时，都会通过 theme 获取配置。</li>
<li>示例<pre><code class="language-javascript">// 定制登录界面UI
mox.theme.logo = {
    logo: &#39;/assets/login_logo.png&#39; // 规范：248x248
};
</code></pre>
</li>
</ul>
<h2>初始化（可选）</h2>
<ul>
<li><p>在 app.js 中初始化:</p>
<pre><code class="language-javascript">mox.init(promisify);
</code></pre>
<p>  promisify 为 false, 只支持 callback 回调写法, 并且可忽略 init 语句
  promisify 为 true 时，表示 mox 同时使用 callback 和 promise 写法</p>
<pre><code class="language-javascript">mox.init(true);
// 以下两种写法均可
mox.login({
    success: () =&gt; {},
    fail: () =&gt; {}
});

mox.login()
    .then(() =&gt; {})
    .catch(() =&gt; {});
</code></pre>
<p>  <font color="red" size="4"><strong>注意： mox.request, mox.audio, mox.recorder 暂不支持 callback 方式</strong></font></p>
</li>
</ul>
<h2>mox 数据</h2>
<ul>
<li>  mox.appid: 获取 APPID</li>
<li>mox.user: 用户信息<pre><code class="language-javascript">{
    openid: &#39;&#39;,    // openid
    unionid: &#39;&#39;,   // unionid 绑定了微信开放平台才有
    nickname: &#39;&#39;,  // 昵称
    avatar: &#39;&#39;,    // 头像
    gender: &#39;&#39;,    // 性别  1男 2女 0未知
    country: &#39;&#39;,   // 国家
    city: &#39;&#39;,      // 城市
    province: &#39;&#39;,  // 省份
    language: &#39;&#39;,  // 语言
}
</code></pre>
</li>
</ul>
<h2>请求</h2>
<h3>mox.request</h3>
<ul>
<li>  功能：网络请求封装</li>
<li>mox.request 会在 header 中自动增加了以下字段，以便服务器端校验<pre><code class="language-javascript">header: {
    appid, openid, unionid, session;
}
</code></pre>
</li>
<li>  mox.request 将会自动获取 src/global.js 中的 server 进行 setHost</li>
</ul>
<h4>mox.request.get()</h4>
<ul>
<li><p>  功能：get 请求</p>
</li>
<li><p>参数
  <code>mox.request.get(path, params, enableCache, expireIn) </code></p>
<table>
<thead>
<tr>
<th>属性名</th>
<th>类型</th>
<th>默认值</th>
<th>描述</th>
</tr>
</thead>
<tbody><tr>
<td>path</td>
<td>string</td>
<td>&#39;&#39;</td>
<td>请求路径，如&#39;/books&#39;，会自动与 setHost 中的 server 拼接起来</td>
</tr>
<tr>
<td>params</td>
<td>object</td>
<td>{}</td>
<td>请求参数，如{&#39;id&#39;: 123}</td>
</tr>
<tr>
<td>enableCache</td>
<td>boolean</td>
<td>false</td>
<td>是否启用缓存，如果开启，会在缓存过期前，优先使用本地 localStorage 缓存数据</td>
</tr>
<tr>
<td>expireIn</td>
<td>number</td>
<td>0</td>
<td>缓存过期时间，单位秒</td>
</tr>
</tbody></table>
</li>
<li><p>  返回： 无</p>
</li>
</ul>
<h4>mox.request.post()</h4>
<ul>
<li>  功能： post 请求</li>
<li>参数
  <code>mox.request.post(path, params)</code></li>
</ul>
<table>
<thead>
<tr>
<th>属性名</th>
<th>类型</th>
<th>默认值</th>
<th>描述</th>
</tr>
</thead>
<tbody><tr>
<td>path</td>
<td>string</td>
<td>&#39;&#39;</td>
<td>请求路径，如&#39;/books&#39;，会自动与 setHost 中的 server 拼接起来</td>
</tr>
<tr>
<td>params</td>
<td>object</td>
<td>{}</td>
<td>请求参数，如{&#39;id&#39;: 123}</td>
</tr>
</tbody></table>
<ul>
<li>  返回： 无</li>
<li>  示例：</li>
</ul>
<pre><code class="language-javascript">mox.request.post(&#39;/cards&#39;, { type: &#39;&#39;, name: &#39;&#39; });
</code></pre>
<h4>mox.request.put()</h4>
<ul>
<li>  功能： put 请求</li>
<li>参数
  <code>mox.request.put(path, params)</code></li>
</ul>
<table>
<thead>
<tr>
<th>属性名</th>
<th>类型</th>
<th>默认值</th>
<th>描述</th>
</tr>
</thead>
<tbody><tr>
<td>path</td>
<td>string</td>
<td>&#39;&#39;</td>
<td>请求路径，如&#39;/books&#39;，会自动与 setHost 中的 server 拼接起来</td>
</tr>
<tr>
<td>params</td>
<td>object</td>
<td>{}</td>
<td>请求参数，如{&#39;id&#39;: 123}</td>
</tr>
</tbody></table>
<ul>
<li>  返回： 无</li>
<li>  示例：</li>
</ul>
<pre><code class="language-javascript">mox.request.put(&#39;/cards/CARD_ID&#39;, { type: &#39;&#39;, name: &#39;&#39; });
</code></pre>
<h4>mox.request.delete()</h4>
<ul>
<li>  功能： delete 请求</li>
<li>参数
  <code>mox.request.delete(path, params)</code></li>
</ul>
<table>
<thead>
<tr>
<th>属性名</th>
<th>类型</th>
<th>默认值</th>
<th>描述</th>
</tr>
</thead>
<tbody><tr>
<td>path</td>
<td>string</td>
<td>&#39;&#39;</td>
<td>请求路径，如&#39;/books&#39;，会自动与 setHost 中的 server 拼接起来</td>
</tr>
<tr>
<td>params</td>
<td>object</td>
<td>{}</td>
<td>请求参数，如{&#39;id&#39;: 123}</td>
</tr>
</tbody></table>
<ul>
<li>  返回： 无</li>
<li>示例：
  <code>mox.request.delete(&#39;/cards/CARD_ID&#39;)</code></li>
</ul>
<h4>mox.request.disableCache()</h4>
<ul>
<li>  功能：禁用缓存：主要是为了在 dev 下统一禁用 request.get 中的 cache</li>
<li>  参数： 无</li>
<li>  返回： 无</li>
<li>示例代码：
  <code>mox.request.disableCache()</code></li>
</ul>
<h2>登录</h2>
<h3>mox.login()</h3>
<ul>
<li><p>  功能：登录，获取用户头像、昵称、unionid 等(要获取 unionid，需要把小程序绑定到微信开发平台<a href="https://open.weixin.qq.com">https://open.weixin.qq.com</a>)</p>
</li>
<li><p>参数：opts (可选)</p>
<table>
<thead>
<tr>
<th>属性名</th>
<th>类型</th>
<th>默认值</th>
<th>描述</th>
</tr>
</thead>
<tbody><tr>
<td>hardMode</td>
<td>boolean</td>
<td>false</td>
<td>是否使用强模式</td>
</tr>
<tr>
<td>ui</td>
<td>boolean</td>
<td>false</td>
<td>未登录时是否自动弹出 UI 登录界面</td>
</tr>
<tr>
<td>title</td>
<td>string</td>
<td>&#39;&#39;</td>
<td>登录界面的提示文字</td>
</tr>
<tr>
<td>loginBtnColor</td>
<td>string</td>
<td>&#39;&#39;</td>
<td>登录按钮颜色，如 #476b70</td>
</tr>
</tbody></table>
</li>
<li><p>  返回： 无</p>
</li>
<li><p>示例:</p>
<pre><code class="language-javascript">mox.login().then(
    data =&gt; {
        // 登录成功，data为
        /*
    {
        openid: &#39;&#39;,
        unionid: &#39;&#39;,
        nickname: &#39;&#39;,
        avatar: &#39;&#39;,
        gender: 0,
        country: &#39;&#39;,
        city: &#39;&#39;,
        province: &#39;&#39;,
        language: &#39;&#39;
    }
    */
    },
    err =&gt; {
        // 登录失败
    }
);
</code></pre>
</li>
<li><p>  <font color="red">hardMode 说明： 强模式下 session 过期时间为 2 分钟， 弱模式下为 24 小时</font></p>
</li>
</ul>
<h2>音频</h2>
<h3>mox.audio</h3>
<ul>
<li>  在使用 wx.createInnerAudioContext()时，有一些坑，业务上也存在需要支持多个文件顺序播放的诉求，故包装了 mox.audio，一方面将一些“坑”统一规避了，另外一方面支持顺序播放多个链接。</li>
</ul>
<h4>mox.audio.play()</h4>
<ul>
<li><p>功能: 在全局通道播放一个或多个音频，当播放多个音频时，中间某一个播放失败，会继续播放后面的；
  新调用 play 会将上次调用的停掉，如果想同时播放多个音频，请调用 mox.audio.createAudioContext 接口创建 audio 实例</p>
</li>
<li><p>参数: opts</p>
<table>
<thead>
<tr>
<th>属性名</th>
<th>类型</th>
<th>默认值</th>
<th>描述</th>
</tr>
</thead>
<tbody><tr>
<td>urls</td>
<td>array, string</td>
<td>[]</td>
<td>需要播放的音频 url，可以是 url 数组，也可以是某个 url</td>
</tr>
<tr>
<td>begin</td>
<td>function</td>
<td></td>
<td>音频开始播放的回调</td>
</tr>
<tr>
<td>progress</td>
<td>function</td>
<td></td>
<td>音频出现加载情况的回调</td>
</tr>
</tbody></table>
</li>
<li><p>  返回： 无</p>
</li>
<li><p>示例:</p>
<pre><code class="language-javascript">// 调用参数参考InnerAudioContextEx.play

// 多个音频
mox.audio.play({
    urls: [&#39;AUDIO_URL_1&#39;, &#39;AUDIO_URL_2&#39;],
    success: res =&gt; {
        // 播放结束，全部成功
        res.result.successed; // 所有音频
    },
    fail: res =&gt; {
        // 播放结束，部分失败
        res.result.successed; // 播放成功的音频
        res.result.failed; // 播放失败的音频
    },
    begin: res =&gt; {
        // 某个音频开始播放时
        res.index; // 当前播放音频的索引
        res.url; // 当前播放音频的url
    },
    progress: res =&gt; {
        // 某个音频出现加载时
        res.index;
        res.url;
    }
});

// 单个音频
mox.audio.play({
    urls: &#39;AUDIO_URL&#39;,
    success: res =&gt; {
        // 播放成功
        res.url; // 传入的音频
    },
    fail: res =&gt; {
        // 播放失败
        res.url;
    },
    begin: res =&gt; {
        res.url;
    },
    progress: res =&gt; {
        res.url;
    }
});
</code></pre>
</li>
</ul>
<h4>mox.audio.stop()</h4>
<ul>
<li>  功能: 停止播放全局通道的音频</li>
<li>  参数: 无</li>
<li>  返回： 无</li>
<li>示例:<pre><code class="language-javascript">mox.audio.stop();
</code></pre>
</li>
</ul>
<h4>mox.audio.pause()</h4>
<ul>
<li>  功能：暂停全局通道的音频</li>
<li>  参数：无</li>
<li>  返回： 无</li>
<li>示例:<pre><code class="language-javascript">mox.audio.pause();
</code></pre>
</li>
</ul>
<h4>mox.audio.resume()</h4>
<ul>
<li>  功能：恢复播放全局通道的音频，如果已经播放完，不会重新开始</li>
<li>  参数：无</li>
<li>  返回： 无</li>
<li>示例:<pre><code class="language-javascript">mox.audio.resume();
</code></pre>
</li>
</ul>
<h4>mox.audio.getGlobalAudio()</h4>
<ul>
<li><p>  功能： 获取全局通道的 globalAudio 对象，该对象在全局唯一， globalAudio 会存放在 <code>mox.audio._audios</code> 中</p>
</li>
<li><p>  参数： 无</p>
</li>
<li><p>  返回： InnerAudioContextEx 对象</p>
</li>
<li><p>  注：调用 mox.audio.play, mox.audio.stop, mox.audio.pause, mox.audio.resume,时，实际上是使用 globalAudio 对象执行</p>
</li>
<li><p>示例：</p>
<pre><code class="language-javascript">let globalAudio = mox.audio.getGlobalAudio();
globalAudio.play();

// 等同于
mox.audio.play();
</code></pre>
</li>
</ul>
<h4>mox.audio.createAudioContext()</h4>
<ul>
<li><p>  功能：创建 audioContext 实例，实现多通道同时播放。所有创建完的 audioContext 将会存放在 <code>mox.audio._audios</code> 中</p>
</li>
<li><p>  参数：无</p>
</li>
<li><p>  返回：InnerAudioContextEx 对象</p>
</li>
<li><p>示例:</p>
<pre><code class="language-javascript">let bgm = mox.audio.createAudioContext();
let url = &#39;https://xxx.mp3&#39;;
bgm.play(url, {
    success: res =&gt; {
        console.log(&#39;play success:&#39;, res);
    },
    fail: res =&gt; {
        // res.err: 错误描述
        console.log(&#39;play fail:&#39;, res);
    },
    complete: res =&gt; {
        console.log(&#39;play complete:&#39;, res);
    }
});
</code></pre>
</li>
</ul>
<h4>mox.audio.destroyAudioContext()</h4>
<ul>
<li>  功能：销毁 <code>mox.audio._audios</code> 中的某个 audioContext 实例</li>
<li>参数：
  <code>mox.audio.destroyAudioContext(audioContext)</code><table>
<thead>
<tr>
<th>属性名</th>
<th>类型</th>
<th>默认值</th>
<th>描述</th>
</tr>
</thead>
<tbody><tr>
<td>audioContext</td>
<td>object</td>
<td>{}</td>
<td>InnerAudioContextEx 对象</td>
</tr>
</tbody></table>
</li>
<li>  返回：无</li>
<li>示例:<pre><code class="language-javascript">let bgm = mox.audio.createAudioContext();
//
///...
mox.audio.destroyAudioContext(bgm);
</code></pre>
</li>
</ul>
<h4>mox.audio.pauseAll()</h4>
<ul>
<li>  功能：暂停 <code>mox.audio._audios</code> 中全部 AudioContext 的播放</li>
<li>  参数：无</li>
<li>  返回： 无</li>
<li>示例:<pre><code class="language-javascript">mox.audio.pauseAll();
</code></pre>
</li>
</ul>
<h4>mox.audio.resumeAll()</h4>
<ul>
<li>  功能：恢复 <code>mox.audio._audios</code> 中全部 AudioContext 的播放</li>
<li>  参数：无</li>
<li>  返回： 无</li>
<li>示例:<pre><code class="language-javascript">mox.audio.resumeAll();
</code></pre>
</li>
</ul>
<h4>mox.audio.stopAll()</h4>
<ul>
<li>  功能：停止 <code>mox.audio._audios</code> 中全部 AudioContext 的播放</li>
<li>  参数：无</li>
<li>  返回： 无</li>
<li>示例:<pre><code class="language-javascript">mox.audio.stopAll();
</code></pre>
</li>
</ul>
<h3>mox.recorder</h3>
<ul>
<li>  功能： 录音器</li>
</ul>
<h4>mox.recorder.createBasicRecorderManager()</h4>
<ul>
<li>  功能：生成一个录音器对象 BasicRecorderManager</li>
<li>  参数： 无</li>
<li>  返回： BasicRecorderManager 对象</li>
<li>  示例：</li>
</ul>
<pre><code class="language-javascript">let recorder = mox.recorder.createBasicRecorderManager();
</code></pre>
<h4>mox.recorder.registerNormalRecorder()</h4>
<ul>
<li><p>  功能：注册录音器对象， 对象将在 <code>mox.recorder.normalRecorders</code> 中保存</p>
</li>
<li><p>参数：
  <code>mox.recorder.registerNormalRecorder(id, recorder)</code></p>
<table>
<thead>
<tr>
<th>属性名</th>
<th>类型</th>
<th>默认值</th>
<th>描述</th>
</tr>
</thead>
<tbody><tr>
<td>id</td>
<td>string</td>
<td>&#39;&#39;</td>
<td>自己命名的录音器 id</td>
</tr>
<tr>
<td>recorder</td>
<td>object</td>
<td></td>
<td>录音器对象</td>
</tr>
</tbody></table>
</li>
<li><p>  示例：</p>
</li>
</ul>
<pre><code class="language-javascript">let recorder = mox.recorder.createBasicRecorderManager();
mox.recorder.registerNormalRecorder(&#39;recorder1&#39;, recorder);
</code></pre>
<h4>mox.recorder.offNormalRecorder()</h4>
<ul>
<li>  功能：销毁录音器对象</li>
<li>参数：
  <code>mox.recorder.registerNormalRecorder(id)</code><table>
<thead>
<tr>
<th>属性名</th>
<th>类型</th>
<th>默认值</th>
<th>描述</th>
</tr>
</thead>
<tbody><tr>
<td>id</td>
<td>string</td>
<td>&#39;&#39;</td>
<td>录音器 id</td>
</tr>
</tbody></table>
</li>
<li>  示例：</li>
</ul>
<pre><code class="language-javascript">mox.recorder.offNormalRecorder(&#39;recorder1&#39;);
</code></pre>
<h4>BasicRecorderManager 类说明</h4>
<ul>
<li>  功能： 对小程序自带的 RecorderManager 进行封装填坑</li>
</ul>
<h5>BasicRecorderManager.start()</h5>
<ul>
<li>  功能：开始录音</li>
<li>  参数 opts</li>
</ul>
<table>
<thead>
<tr>
<th>属性名</th>
<th>类型</th>
<th>默认值</th>
<th>描述</th>
</tr>
</thead>
<tbody><tr>
<td>sample</td>
<td>number</td>
<td>8000</td>
<td>采样率</td>
</tr>
<tr>
<td>channel</td>
<td>number</td>
<td>2</td>
<td>通道</td>
</tr>
<tr>
<td>bitrate</td>
<td>number</td>
<td>48000</td>
<td>码率</td>
</tr>
<tr>
<td>format</td>
<td>string</td>
<td>&#39;aac&#39;</td>
<td>文件格式</td>
</tr>
<tr>
<td>duration</td>
<td>number</td>
<td>60000</td>
<td>录音时长</td>
</tr>
<tr>
<td>onStart</td>
<td>function</td>
<td></td>
<td>录音正式开始回调</td>
</tr>
</tbody></table>
<ul>
<li><p>  返回：无</p>
</li>
<li><p>  各属性的枚举，参照 <a href="https://developers.weixin.qq.com/miniprogram/dev/api/media/recorder/RecorderManager.start.html">https://developers.weixin.qq.com/miniprogram/dev/api/media/recorder/RecorderManager.start.html</a></p>
</li>
</ul>
<h5>BasicRecorderManager.stop()</h5>
<ul>
<li>  功能：停止录音</li>
<li>  参数： 无</li>
<li>  返回： 无</li>
</ul>
<h4>component 模式</h4>
<h5>normal-recorder 组件</h5>
<ul>
<li><p>  功能： mox.recorder 的 UI 版本</p>
</li>
<li><p>使用方式：</p>
<ol>
<li><p>引入 normal-recorder 组件</p>
<pre><code class="language-json">// index.json
{
 &quot;usingComponents&quot;: {
     &quot;normal-recorder&quot;: &quot;../../mox-weapp/components/normal_recorder&quot;
 }
}
</code></pre>
</li>
<li><p>在 wxml 中使用组件</p>
<pre><code class="language-html">&lt;!-- index.wxml --&gt;
&lt;normal-recorder&gt;&lt;/normal-recorder&gt;
</code></pre>
</li>
<li><p>调用</p>
</li>
</ol>
<ul>
<li><p>长按模式</p>
<pre><code class="language-html">&lt;!-- index.wxml --&gt;
&lt;normal-recorder mode=&quot;touch&quot; id=&quot;recorder&quot;&gt;&lt;/normal-recorder&gt;
</code></pre>
<pre><code class="language-javascript">// index.js
onReady () {
  this.recorder = this.selectComponent(&quot;#recorder&quot;);
  this.recorder.start({
  onStart:()=&gt;{

  },
  complete:(res)=&gt;{

  }
  })
}
</code></pre>
</li>
<li><p>js 调用模式</p>
<pre><code class="language-html">&lt;!-- index.wxml --&gt;
&lt;normal-recorder id=&quot;recorder&quot;&gt;&lt;/normal-recorder&gt;
</code></pre>
<pre><code class="language-javascript">// index.js
onReady () {
  this.recorder = this.selectComponent(&quot;#recorder&quot;);
}
beginTouchRecord(){
  // 用户按下开始录音按钮执行
  this.recorder.start({
      onStart:()=&gt;{

      },
      complete:(res)=&gt;{

      }
  })
},
endTouchRecord(){
  // 用户按下录音结束按钮执行
  this.recorder.stop()
},
</code></pre>
</li>
</ul>
</li>
</ul>
<h2>预加载</h2>
<h3>mox.preload</h3>
<ul>
<li>  功能： 预加载资源(图片或视频)</li>
</ul>
<h4>mox.preload.load()</h4>
<ul>
<li>  功能：加载资源列表</li>
<li>  参数：opts</li>
</ul>
<table>
<thead>
<tr>
<th>属性名</th>
<th>类型</th>
<th>默认值</th>
<th>描述</th>
</tr>
</thead>
<tbody><tr>
<td>urls</td>
<td>array</td>
<td>string</td>
<td>&#39;&#39;</td>
</tr>
<tr>
<td>timeout</td>
<td>number</td>
<td>10000</td>
<td>每个 url 预加载的超时时间，单位 ms</td>
</tr>
<tr>
<td>progress</td>
<td>function</td>
<td></td>
<td>进度回调</td>
</tr>
</tbody></table>
<ul>
<li>  返回： 无</li>
<li>  progress 回调参数 res</li>
</ul>
<table>
<thead>
<tr>
<th>属性名</th>
<th>类型</th>
<th>描述</th>
</tr>
</thead>
<tbody><tr>
<td>url</td>
<td>string</td>
<td>当前完成的 url</td>
</tr>
<tr>
<td>current</td>
<td>number</td>
<td>当前完成个数</td>
</tr>
<tr>
<td>total</td>
<td>function</td>
<td>总个数</td>
</tr>
</tbody></table>
<h4>mox.preload.getPath()</h4>
<ul>
<li>  功能：获取预加载后的路径，若 url 未预加载，则直接返回 url</li>
<li>  参数：url</li>
</ul>
<table>
<thead>
<tr>
<th>属性名</th>
<th>类型</th>
<th>描述</th>
</tr>
</thead>
<tbody><tr>
<td>url</td>
<td>string</td>
<td>资源的网络链接</td>
</tr>
</tbody></table>
<ul>
<li>  返回： 无</li>
</ul>
<h2>广告</h2>
<h3>mox.ad</h3>
<ul>
<li>  功能： 提供激励视频广告和插屏广告的显示</li>
</ul>
<h4>mox.ad.init()</h4>
<ul>
<li>  功能：初始化广告</li>
<li>  参数 opts</li>
</ul>
<table>
<thead>
<tr>
<th>属性名</th>
<th>类型</th>
<th>默认值</th>
<th>描述</th>
</tr>
</thead>
<tbody><tr>
<td>type</td>
<td>string</td>
<td>&#39;&#39;</td>
<td>广告类型</td>
</tr>
<tr>
<td>config</td>
<td>object</td>
<td>{}</td>
<td>广告配置</td>
</tr>
</tbody></table>
<ul>
<li>  返回： 无</li>
<li>  type 可选值</li>
</ul>
<table>
<thead>
<tr>
<th>值</th>
<th>描述</th>
</tr>
</thead>
<tbody><tr>
<td>reward</td>
<td>激励视频广告</td>
</tr>
<tr>
<td>interstitial</td>
<td>插屏广告</td>
</tr>
</tbody></table>
<ul>
<li>  config 配置</li>
</ul>
<table>
<thead>
<tr>
<th>属性名</th>
<th>类型</th>
<th>默认值</th>
<th>描述</th>
</tr>
</thead>
<tbody><tr>
<td>id</td>
<td>string</td>
<td>&#39;&#39;</td>
<td>广告 unit-id</td>
</tr>
</tbody></table>
<ul>
<li>  示例：</li>
</ul>
<pre><code class="language-javascript">let ad = mox.ad.init({
    type: &#39;reward&#39;,
    config: {
        id: &#39;adunit-xxxxxxxxxxxxx&#39;
    }
});
</code></pre>
<h4>mox.ad.show()</h4>
<ul>
<li>  功能：显示广告</li>
<li>  参数：opts</li>
<li>  返回：无</li>
<li>  success 回调参数 res</li>
</ul>
<table>
<thead>
<tr>
<th>属性名</th>
<th>类型</th>
<th>描述</th>
</tr>
</thead>
<tbody><tr>
<td>isEnd</td>
<td>boolean</td>
<td>是否看完了广告（仅适用于激励广告，插屏广告会永远返回 true）</td>
</tr>
<tr>
<td>isError</td>
<td>boolean</td>
<td>是否是因为 wx 广告单元出错导致的成功</td>
</tr>
</tbody></table>
<ul>
<li>  <font color="red">由于之前接入广告时，发现广告单元经常报错，且广告不属于主线逻辑。所以将报错情况一律视为看完了广告</font></li>
</ul>
<h2>支付</h2>
<h3>mox.payment</h3>
<ul>
<li>  功能： 封装微信支付的所有步骤</li>
</ul>
<h4>mox.payment.createOrder()</h4>
<ul>
<li>  功能：创建支付订单</li>
<li>  参数： opts</li>
</ul>
<table>
<thead>
<tr>
<th>属性名</th>
<th>类型</th>
<th>默认值</th>
<th>描述</th>
</tr>
</thead>
<tbody><tr>
<td>title</td>
<td>string</td>
<td>&#39;&#39;</td>
<td>标题</td>
</tr>
<tr>
<td>price</td>
<td>number</td>
<td>0</td>
<td>价格</td>
</tr>
<tr>
<td>detail</td>
<td>object, string</td>
<td>&#39;&#39;</td>
<td>备注</td>
</tr>
</tbody></table>
<ul>
<li>  返回： 无</li>
<li>  success 回调参数 res</li>
</ul>
<table>
<thead>
<tr>
<th>属性名</th>
<th>类型</th>
<th>描述</th>
</tr>
</thead>
<tbody><tr>
<td>orderId</td>
<td>string</td>
<td>订单 id</td>
</tr>
<tr>
<td>payArgs</td>
<td>object</td>
<td>订单支付信息</td>
</tr>
</tbody></table>
<h4>mox.payment.submitPayment()</h4>
<ul>
<li>  功能：拉起支付</li>
<li>  参数： opts</li>
</ul>
<table>
<thead>
<tr>
<th>属性名</th>
<th>类型</th>
<th>默认值</th>
<th>描述</th>
</tr>
</thead>
<tbody><tr>
<td>orderInfo</td>
<td>object</td>
<td>{}</td>
<td>订单信息</td>
</tr>
</tbody></table>
<ul>
<li>  返回： 无</li>
<li>  success 回调参数 res</li>
</ul>
<table>
<thead>
<tr>
<th>属性名</th>
<th>类型</th>
<th>描述</th>
</tr>
</thead>
<tbody><tr>
<td>orderId</td>
<td>string</td>
<td>订单 id</td>
</tr>
</tbody></table>
<ul>
<li>示例<pre><code class="language-javascript">mox.payment.createOrder({
    title: &#39;解锁&#39;,
    price: 0.01,
    detail: &#39;解锁用户测试分数&#39;,
    success: orderInfo =&gt; {
        mox.payment.submitPayment({
            orderInfo: orderInfo,
            success: () =&gt; {
                console.log(&#39;支付成功&#39;);
            }
        });
    }
});
</code></pre>
</li>
</ul>
<h4>mox.payment.pay()</h4>
<ul>
<li>  功能： 集成 createOrder 与 submitPayment 功能</li>
<li>  参数： 同 mox.payment.createOrder</li>
<li>  返回： 无</li>
</ul>
<h2>文件上传</h2>
<h3>mox.file</h3>
<ul>
<li>  功能： 封装选择图片，上传文件等功能</li>
</ul>
<h4>mox.file.chooseImage()</h4>
<ul>
<li>  功能： 实现选择图片，并且直接上传（可选）</li>
<li>  参数 opts</li>
</ul>
<table>
<thead>
<tr>
<th>属性名</th>
<th>类型</th>
<th>默认值</th>
<th>描述</th>
</tr>
</thead>
<tbody><tr>
<td>count</td>
<td>number</td>
<td>9</td>
<td>选择图片的最大数量</td>
</tr>
<tr>
<td>sizeType</td>
<td>array</td>
<td>[&#39;compressed&#39;]</td>
<td>图片质量</td>
</tr>
<tr>
<td>sourceType</td>
<td>array</td>
<td>[&#39;album&#39;]</td>
<td>图片来源</td>
</tr>
<tr>
<td>upload</td>
<td>boolean</td>
<td>true</td>
<td>是否自动上传</td>
</tr>
<tr>
<td>showProgress</td>
<td>boolean</td>
<td>false</td>
<td>是否显示上传进度 loading</td>
</tr>
</tbody></table>
<ul>
<li>  返回： 无</li>
<li>  sizeType 可选值</li>
</ul>
<table>
<thead>
<tr>
<th>属性名</th>
<th>描述</th>
</tr>
</thead>
<tbody><tr>
<td>original</td>
<td>原图</td>
</tr>
<tr>
<td>compressed</td>
<td>压缩图</td>
</tr>
</tbody></table>
<ul>
<li>  sourceType 可选值</li>
</ul>
<table>
<thead>
<tr>
<th>属性名</th>
<th>描述</th>
</tr>
</thead>
<tbody><tr>
<td>album</td>
<td>从相册选图</td>
</tr>
<tr>
<td>camera</td>
<td>使用相机</td>
</tr>
</tbody></table>
<ul>
<li>  示例：</li>
</ul>
<pre><code class="language-javascript">mox.file.chooseImage({
    count: 1,
    sizeType: [&#39;compressed&#39;],
    sourceType: [&#39;album&#39;, &#39;camera&#39;],
    upload: true,
    showProgress: true,
    success: res =&gt; {}
});
</code></pre>
<h4>mox.file.uploadFile()</h4>
<ul>
<li>  功能： 上传文件</li>
<li>  参数 opts</li>
</ul>
<table>
<thead>
<tr>
<th>属性名</th>
<th>类型</th>
<th>默认值</th>
<th>描述</th>
</tr>
</thead>
<tbody><tr>
<td>filePath</td>
<td>string</td>
<td>&#39;&#39;</td>
<td>需要上传的文件路径</td>
</tr>
<tr>
<td>progress</td>
<td>function</td>
<td></td>
<td>上传进度改变时的回调</td>
</tr>
</tbody></table>
<ul>
<li>  返回： 无</li>
<li>  progress 回调参数 res</li>
</ul>
<table>
<thead>
<tr>
<th>属性名</th>
<th>类型</th>
<th>描述</th>
</tr>
</thead>
<tbody><tr>
<td>progress</td>
<td>number</td>
<td>上传进度百分比</td>
</tr>
</tbody></table>
<ul>
<li>  success 回调参数 res</li>
</ul>
<table>
<thead>
<tr>
<th>属性名</th>
<th>类型</th>
<th>描述</th>
</tr>
</thead>
<tbody><tr>
<td>key</td>
<td>string</td>
<td>图片本地路径</td>
</tr>
<tr>
<td>sec_task_id</td>
<td>string</td>
<td>上传任务 id</td>
</tr>
<tr>
<td>url</td>
<td>string</td>
<td>图片上传成功后的链接</td>
</tr>
</tbody></table>
<ul>
<li>  示例：</li>
</ul>
<pre><code class="language-javascript">mox.file.uploadFile({
    filePath: &#39;FILE_PATH&#39;,
    success: res =&gt; {
        let url = res.url; // 图片链接
    }
});
</code></pre>
<h4>mox.file.uploadFiles()</h4>
<ul>
<li>  功能： uploadFile 的复数版本</li>
<li>  参数 opts</li>
</ul>
<table>
<thead>
<tr>
<th>属性名</th>
<th>类型</th>
<th>默认值</th>
<th>描述</th>
</tr>
</thead>
<tbody><tr>
<td>filePaths</td>
<td>array</td>
<td>[]</td>
<td>需要上传的文件路径数组</td>
</tr>
<tr>
<td>progress</td>
<td>function</td>
<td></td>
<td>上传进度改变时的回调</td>
</tr>
</tbody></table>
<ul>
<li>  返回： 无</li>
<li>  progress 回调参数 res</li>
</ul>
<table>
<thead>
<tr>
<th>属性名</th>
<th>类型</th>
<th>描述</th>
</tr>
</thead>
<tbody><tr>
<td>current</td>
<td>object</td>
<td>当前文件上传信息</td>
</tr>
<tr>
<td>total</td>
<td>object</td>
<td>所有文件上传信息</td>
</tr>
</tbody></table>
<ul>
<li>  success 回调参数 res</li>
</ul>
<table>
<thead>
<tr>
<th>属性名</th>
<th>类型</th>
<th>描述</th>
</tr>
</thead>
<tbody><tr>
<td>total</td>
<td>object</td>
<td>所有文件上传信息</td>
</tr>
</tbody></table>
<ul>
<li>  示例：</li>
</ul>
<pre><code class="language-javascript">mox.file.uploadFiles({
    filePaths: [&#39;FILE_PATH_1&#39;, &#39;FILE_PATH_2&#39;],
    success: res =&gt; {}
});
</code></pre>
<h2>实时日志管理器</h2>
<h3>mox.log</h3>
<ul>
<li>  功能：对小程序本身的 RealtimeLogManager 的 封装</li>
<li>  接口参数 参照 console 及 RealtimeLogManager</li>
<li>  <font color="red">不同于 console，该管理器可将信息传输到小程序后台进行查看</font></li>
</ul>
<h4>mox.log.debug()</h4>
<h4>mox.log.info()</h4>
<h4>mox.log.warn()</h4>
<h4>mox.log.error()</h4>
<h4>mox.log.setFilterMsg()</h4>
<h4>mox.log.addFilterMsg()</h4>
<h2>应用升级</h2>
<h3>mox.checkAppUpdateAndApply()</h3>
<ul>
<li>  功能：检查小程序版本并提示升级</li>
<li>  参数： 无</li>
<li>  返回： 无</li>
<li>  示例：</li>
</ul>
<pre><code class="language-javascript">mox.checkAppUpdateAndApply();
</code></pre>
<h1>三、版本历史</h1>
<ul>
<li><p>2.0.0 —— 2021-02-27</p>
<ul>
<li>重构 mox<ul>
<li>  将目前所有提供给外部调用的接口，参数统一为 object</li>
<li>  支持 接口的 promise 方式</li>
</ul>
</li>
<li>  重写 ad 模块， 提供激励视频广告和插屏广告的接口</li>
<li>  补充所有接口的 readme</li>
</ul>
</li>
<li><p>1.6.0 —— 2021-01-21</p>
<ul>
<li>  mox 增加方法 checkAppUpdateAndApply 统一检查应用更新以及强制版本升级</li>
</ul>
</li>
<li><p>1.5.8 —— 2021-01-13</p>
<ul>
<li>  修复 request 在 updateSession 调用以前发出的网络请求没有 appid 问题</li>
</ul>
</li>
<li><p>1.5.7 —— 2021-01-07</p>
<ul>
<li>  request 支持定制 headers</li>
</ul>
</li>
<li><p>1.5.6 —— 2021-01-07</p>
<ul>
<li>  增加软登录模块</li>
</ul>
</li>
<li><p>1.5.5 —— 2021-01-07</p>
<ul>
<li>  增加参数修改登陆按钮背景色</li>
</ul>
</li>
<li><p>1.5.4 —— 2020-07-30</p>
<ul>
<li>  录音组件提供注册/注销机制</li>
</ul>
</li>
<li><p>1.5.3 —— 2020-07-08</p>
<ul>
<li>  增加录音组件增加 beforeStart 接口</li>
</ul>
</li>
<li><p>1.5.2 —— 2020-07-07</p>
<ul>
<li>  增加录音模块和录音组件</li>
</ul>
</li>
<li><p>1.5.1 —— 2020-04-02</p>
<ul>
<li>  优化 session 的 login，在 login 失败时，清理缓存的 session</li>
<li>  优化文件上传 mox.uploadFile 接口，文件上传通过任务异步检查校验结果</li>
</ul>
</li>
<li><p>1.5.0 —— 2020-03-17</p>
<ul>
<li>  增加 mox.preload 模块，实现预加载管理</li>
<li>  mox.audio 内部接入 preload，优先使用 preload 资源</li>
<li>  mox.login 支持通过参数指定登录提示语</li>
</ul>
</li>
<li><p>1.4.1 —— 2020-03-12</p>
<ul>
<li>  修复 mox.audio 在 stop 或者通道被顶替后，未调用 complete 的问题</li>
</ul>
</li>
<li><p>1.4.0 —— 2020-03-09</p>
<ul>
<li>  mox.audio 监听 onAudioInterruptionEnd 事，修复在 iOS 下下拉导致无法继续播放，无回调的问题(<a href="https://developers.weixin.qq.com/community/develop/doc/0006c276a6c430d8cb285121a5b000?_at=1583746710639">https://developers.weixin.qq.com/community/develop/doc/0006c276a6c430d8cb285121a5b000?_at=1583746710639</a>)</li>
<li>  mox.audio 增加 createAudioContext 和 destroyAudioContext 接口，用于支持同时播放多个音频</li>
<li>  增加 replay 接口：重新播放</li>
</ul>
</li>
<li><p>1.3.1 —— 2020-03-06</p>
<ul>
<li>  修复 mox.audio 在 iOS 中，当尚未 onBegin 就关闭小程序，再 resume 无法继续播放的问题</li>
</ul>
</li>
<li><p>1.3.0 —— 2020-02-26</p>
<ul>
<li>  增加 audio 模块，提供播放音频文件的封装，支持多个文件顺序播放</li>
<li>  mox.login 接口增加对 session_key 过期的保护</li>
</ul>
</li>
<li><p>1.2.0</p>
<ul>
<li>  增加 mox.login 接口，实现弹窗获取用户头像、昵称以及 unionid 逻辑</li>
<li>  增加 theme 模块，用于支持定制模块的 UI 风格</li>
</ul>
</li>
<li><p>1.1.0</p>
<ul>
<li>  增加 mox.request 模块，提供给业务发送请求，将 appid、openid、unionid 等放在 header 中</li>
<li>  增加 handle_ad 接口，支持“统一广告处理”逻辑</li>
</ul>
</li>
<li><p>1.0.0</p>
<ul>
<li>  基础的 session、openid 获取等逻辑</li>
<li>  微信支付:payment</li>
<li>  showModal、previewImage</li>
</ul>
</li>
</ul>
